home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / tuner / update.c < prev   
Encoding:
C/C++ Source or Header  |  1993-06-06  |  27.5 KB  |  974 lines

  1. /*    UPDATE . C
  2. #
  3. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  4.  
  5. This software is copyright (C) by the Lawrence Berkeley Laboratory.
  6. Permission is granted to reproduce this software for non-commercial
  7. purposes provided that this notice is left intact.
  8.  
  9. It is acknowledged that the U.S. Government has rights to this software
  10. under Contract DE-AC03-765F00098 between the U.S.  Department of Energy
  11. and the University of California.
  12.  
  13. This software is provided as a professional and academic contribution
  14. for joint exchange. Thus, it is experimental, and is provided ``as is'',
  15. with no warranties of any kind whatsoever, no support, no promise of
  16. updates, or printed documentation. By using this software, you
  17. acknowledge that the Lawrence Berkeley Laboratory and Regents of the
  18. University of California shall have no liability with respect to the
  19. infringement of other copyrights by any part of this software.
  20.  
  21. For further information about this notice, contact William Johnston,
  22. Bld. 50B, Rm. 2239, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  23. (wejohnston@lbl.gov)
  24.  
  25. For further information about this software, contact:
  26.     Jin Guojun
  27.     Bld. 50B, Rm. 2275, Lawrence Berkeley Laboratory, Berkeley, CA, 94720.
  28.     g_jin@lbl.gov
  29.  
  30. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  31. %
  32. %    Run time handlers to update picture, and file handling
  33. %    Including:
  34. %        Panel_init(), MapColor(), SetColormap(),
  35. %        FileAccess(), LoadFile(), HistoHandle().
  36. %
  37. %    The Panel_init() build a control panel for both color and
  38. %    gray-scale interactive analyst.
  39. %
  40. % AUTHOR:    Jin Guojun - LBL    4/1/1991
  41. */
  42.  
  43. #ifndef    ETAButtonColor
  44. #define    ETAButtonColor    3
  45. #endif
  46.  
  47. #include "tuner.h"
  48.  
  49. #ifdef    C_TUNER
  50. char    *FRM[] = {"Red", "Green", "Blue", "Sync"};
  51. #else
  52. char    *FRM[] = {"  0/000", "Frame", "Prev", "Next"};
  53. #endif
  54.  
  55.  
  56. Panel_init(parent, ela_scale, PBGcolor, map_panel)
  57. WinAttribute    *parent;
  58. {
  59. char    buf[128];
  60.  
  61. sprintf(buf, "Elasitc TUNER and ANALYZER -- %d %s", ncolors,
  62. #ifdef    C_TUNER
  63. "colors"
  64. #else
  65. "grey levels"
  66. #endif
  67. );
  68. Epanel = CreatePanel(100, 200, 512, 360, buf, parent,
  69.         EnterWindowMask | LeaveWindowMask);
  70. XSetWindowBackground(parent->dpy, Epanel->win, PBGcolor);
  71. if (map_panel)
  72.     XMapWindow(Epanel->dpy, Epanel->win);
  73.  
  74. fontWidth = Epanel->font_w;
  75. fontHeight = Epanel->font_h;
  76.  
  77.     /*    Quantization    */
  78. QSlider = CreateSlider(Epanel, 192, 270, 5, -300, 100, 1, 0, "Quantizing", "",
  79.         Blue, lightGray);
  80.  
  81. #ifdef    C_TUNER
  82. QButton = CreateButton(Epanel, 144, 261, 2, "Fixed Panel Color", NF,
  83.         Visible, Light);
  84. fButton = CreateButton(Epanel, 64, 51, 4, "Channel", FRM, Visible, Light);
  85. QSlider->valid = False;        /* never used, but easy.    */
  86. ButtonState(QButton) = True;    /* Change colors with image    */
  87. #else
  88. QButton = CreateButton(Epanel, 16, 261, 2, "", NF, Visible, Light);
  89. fButton = CreateButton(Epanel, 16, 51, 4, "", FRM, Visible, Light);
  90. /* fButton = CreateButton(Epanel, 64, 51, 3, "Frame", FRM, Visible, Gray);*/
  91. strcpy(filelist[MENU3_LDFrm-1], "......");    /* invalid */
  92. #endif
  93.  
  94. ESlider = CreateSlider(Epanel, 75, 174, ela_scale, -200*ela_scale, 200*ela_scale,
  95.     1, 0, "Tuner", "<- Gamma -> | <-  S  -> | <- Gamma ->", White, Visible);
  96. SetSBarRPos(ESlider, 0, 1);
  97. LSlider = CreateSlider(Epanel, 100, 174, 1, 0, 255, 2, 0, "Scale", "Linear",
  98.         White, lightGray);
  99. DButton = CreateButton(Epanel, 50, 303, 2, "DATA", DUP, Visible, Light);
  100.     /*    clip control    */
  101. CSlider = CreateSlider(Epanel, 312, 72, 2, 0, 254, 2, 0, "Clip", "",
  102.         Blue, lightGray);
  103. SetSBarRPos(CSlider, 254, 2);    /* init    to no clip */
  104. Interpolate = CreateButton(Epanel, 420, 261, 2, "Interpolation", NF,
  105.         Visible, Light);
  106.     /* Other Buttons */
  107. ZButton = CreateButton(Epanel, 420, 204, 2, "ZERO", NF, Visible, Light);
  108. EButton = CreateButton(Epanel, 100, 204, 3, "Emphasis", BN1,
  109.         lightGray, parent->dpy_depth==8 ? ETAButtonColor : Blue);
  110. RstButt = CreatePressButton(Epanel, 354, 300, "RESET", Gray);
  111. rfsButt = CreatePressButton(Epanel, 435, 300, "Refesh", Gray);
  112. FButton = CreateButton(Epanel, 16, 12, 3, "", BNF, Visible, Light);
  113. hButton = CreateButton(Epanel, 16, 96, 5, "", HST, Visible, Light);
  114. heqButt = CreatePressButton(Epanel, 435, 96, "histeq", Light);
  115. slider = LSlider;            /* overlayed, init to linear */
  116. ButtonState(EButton) = ETALinear;    /* init to linear */
  117.     /* PULL DOWN MENU */
  118. ctrlmenu = CreatePopMenu(Epanel, parent, "Editer", ctrlist, numctrl);
  119. paramenu = CreatePopMenu(Epanel, parent, "SCALEs", paralist, numpara);
  120. filemenu = CreatePopMenu(Epanel, parent, "FILE", filelist, numcomd);
  121. fontmenu = CreatePopMenu(Epanel, parent, "Fonts", fontlist, numfont);
  122. NoteWin = CreatePanel(10, 10, 256, 128, "MESSAGE", parent, NULL);
  123. InfoWin = CreatePanel(10, 10, 512, 256, "Information", parent, NULL);
  124. MsgButton = CreateButton(NoteWin, 24, 16, 1, "", NOTEMSG, Visible, Gray);
  125. YesButt = CreatePressButton(NoteWin, 48, 80, " Yes ", Light);
  126. NoButt = CreatePressButton(NoteWin, 144, 80, " No ", Light);
  127. OkButt = CreatePressButton(NoteWin, 96, 80, " OK ", Light);
  128. AbortButt = CreatePressButton(NoteWin, 96, 80, " Abort ", Light);
  129.  
  130. return    map_panel;
  131. }
  132.  
  133. /*===============================================
  134. %    to reset original image parameter    %
  135. ===============================================*/
  136. void
  137. ResetORange(img)
  138. Image    *img;
  139. {
  140. register Mregister*    mmm;
  141.     if (img->setscale)
  142.         mmm = &(img->mmm);
  143.     else if (img->color_dpy)
  144.         mmm = img->marray + img->fn%img->channels;
  145.     else    mmm = img->marray + img->fn;
  146.     if (mmm->max < mmm->min  || mmm->max < VCTEntry)
  147.         mmm->max = MaxColors-1;    /* never show small max value */
  148.     SetSBarRPos(LSlider, img->linearlow=
  149. #ifdef    DIRECT
  150.         MAX(VCTEntry, mmm->min), 1);
  151. #else
  152.         mmm->min, 1);
  153. #endif
  154.     SetSBarRPos(LSlider, img->linearup=mmm->max, 2);
  155.     if (slider==LSlider)
  156.         DrawSlider(slider);
  157. }
  158.  
  159.  
  160. /* RETURNs:    (-1) newfile;    (n) reload n;    (0) save, or errors for load */
  161.  
  162. static    char    tbuf[128];
  163.  
  164. FileAccess(imgp, max_num, noi)    /* number of images in stack */
  165. Image    *imgp[];
  166. {
  167. FILE*    fp;
  168. char    info[128], errinfos[32];
  169. register int    i=0;
  170. bool    state=i;
  171. struct    stat    statbuf;
  172. #define    PCloseWin    "Not enough memory. Press 'c' to close some image"
  173.  
  174. if (ButtonState(FButton)==FileSave) {
  175.     for (i=noi; i--;)
  176.     if (imgp[i]->active)    break;
  177.     if (i<0)    goto    FDone;        /* no active image */
  178.     strcpy(tbuf, imgp[noi=i]->name);    /* noi point to active image */
  179.     if (imgp[noi]->frames > 1 &&
  180.     YesOrNo("Save ALL frames ? YES/NO\n(NO, save current frame)",
  181.     NoteWin->font_h))    {
  182.         imgp[noi]->save_all = imgp[noi]->frames;
  183.     }    else    imgp[noi]->save_all = imgp[noi]->frames<=1;
  184.     PressButtonState(YesButt) = PressButtonState(NoButt) = RESETSTATE;
  185. }
  186. FRedo:    DispInfo(Epanel, 0,
  187.     "INPUT -- TAB to cat, BS to correct, ESC undo or TYPE new one",    Yellow);
  188. if (state=TextLine(FButton, tbuf, sizeof(tbuf), 0, Exposure_handler, imgp, noi))
  189.     switch (ButtonState(FButton))    {
  190.     case FileLoad:
  191.         if (noi >= max_num)    {
  192.             for (i=noi; i--;)
  193.                 if (strcmp(tbuf, imgp[i]->name)==0)    break;
  194.             if (i<0)    {
  195.                 XBell(Epanel->dpy, state=0);
  196.                 WaitOk(NULL, PCloseWin, 0);
  197.                 break;
  198.             }
  199.             fsize = imgp[noi=i]->width*imgp[i]->height;
  200.         }
  201.         if (imgp[noi] && imgp[noi]->update)    {
  202.             sprintf(info, "save %s ? y/n", imgp[noi]->name);
  203.             i = (strlen(info)+2) * Epanel->font_w;
  204.             DispInfo(Epanel, 0, info, white1);
  205.             info[0] = 0;
  206.             TextLine(FButton, info, sizeof(info), i,
  207.                 Exposure_handler, imgp, noi);
  208.             if (info[0] != 'n')    {
  209.             char    sbuf[128];
  210.                 strcpy(sbuf, tbuf);
  211.                 ButtonState(FButton) = FileSave;
  212.                 FileAccess(imgp, max_num, noi+1);
  213.                 strcpy(tbuf, sbuf);
  214.             }
  215.         }
  216.         sprintf(info, "Loading file %s", tbuf);
  217.         DispInfo(Epanel, 0, info, Red);
  218.         state = (int)(fp=freopen(tbuf, "rb", stdin));
  219.         if (state) {
  220.             if    (state=LoadImage(fp, imgp+noi, tbuf))
  221.             if (state>0)    state = EOF;
  222.             else /* < 0 */    state = noi;
  223.             else    sprintf(errinfos, "%s is wrong File", tbuf);
  224.         }
  225.         else    sprintf(errinfos, "File not found");
  226.         if (!state){
  227.             DispInfo(Epanel, (strlen(info)+1)*Epanel->font_w,
  228.                 errinfos, Green);
  229.             XBell(Epanel->dpy, state);
  230.             WaitOk(NULL, errinfos, 0);
  231.         }
  232.         break;
  233.     case FileSave:
  234.         if (!stat(tbuf, &statbuf)) {
  235.             TopWindow(Epanel, 0);
  236.             DrawPanel();    XFlush(Epanel->dpy);
  237.             sprintf(info, "file %s exist! overwrite ? y/n", tbuf);
  238.             DispInfo(Epanel, 0, info, White);
  239.             i = strlen(info);
  240.             info[0] = 0;
  241.             TextLine(FButton, info, 2, ++i*Epanel->font_w,
  242.                 Exposure_handler, imgp, noi);
  243.             if (info[0] == Esc)    break;
  244.             if (info[0] != 'y')    goto    FRedo;
  245.         }
  246.         fp = freopen(tbuf, "wb", stdout);
  247.         if (!fp){
  248.             DispInfo(Epanel, 256, "can't open", Green);
  249.             XBell(Epanel->dpy, state=0);
  250.             WaitOk(NULL, sys_errlist[errno], 0);
  251.         }
  252.         else {
  253.             imgp[noi]->OUT_FP = fp;
  254.             if (imgp[noi]->o_type != RLE) {
  255.             register Image* img=imgp[noi];
  256.             register char    *av[1];
  257.             int    frames = img->frames,
  258.                 save_info = img->pixmap_failed;
  259.             i = img->save_all;
  260.             if (!i)    i++;
  261.             img->frames = i;
  262.             img->pxl_out = 1;
  263.             img->o_form = IFMT_BYTE;
  264.             ((U_IMAGE*)img)->update_header = (*img->header_handle)
  265.                     (HEADER_TO, img, 0, No);
  266.             sprintf(info, "writing %s", tbuf);
  267.             DispInfo(Epanel, 0, info, White);
  268.             i = ReadSlider(ESlider, 1);
  269.             sprintf(info, "%s ETA -f%d, bf=%d\n",
  270.                 Progname, i, img->curve);
  271.         /* only output a sub-image when img is a single frame image */
  272.             av[0] = info;
  273.             (*img->header_handle)(HEADER_WRITE, img,
  274.                         1, av, img->update);
  275.             img->frames = frames;
  276.             state=(*img->std_swif)(FI_SAVE_FILE, img, NULL,
  277.                 img->save_all ? 0 : img->fn);
  278.             img->pixmap_failed = save_info;
  279.             }
  280.             else {
  281.             register Image* img=imgp[noi];
  282.             bool    add_cmap=0, save_cur=0;
  283.             if (img->dpy_channels==3 || !OsameI) {
  284.                 add_cmap = YesOrNo("apply screen color map ?", 0);
  285.                 PressButtonState(YesButt) =
  286.                 PressButtonState(NoButt) = RESETSTATE;
  287.                 if (img->channels == 3)/* don't save cmap */
  288.                     rle_dflt_hdr.ncmap = 0;
  289.             }
  290.             else if (img->cmaplen && img->in_cmap)
  291.                 regmap_to_rlemap(img->in_cmap, img->cmaplen,
  292.                         img->ncmap, &rle_dflt_hdr);
  293.             save_cur = YesOrNo("save current setting ?", 0);
  294.             PressButtonState(YesButt) =
  295.             PressButtonState(NoButt) = RESETSTATE;
  296.             memcpy(&cmn_hd, img, sizeof(cmn_hd));
  297.             (*img->std_swif)(FI_DESC_ETA, &cmn_hd, info, cer);
  298.             if (rle_dflt_hdr.comments)
  299.                 rle_dflt_hdr.comments[0] = str_save(cmn_hd.desc);
  300.             sprintf(info, "writing %s", tbuf);
  301.             DispInfo(Epanel, 0, info, White);
  302.             state = (*img->std_swif)(FI_SAVE_FILE, img, add_cmap,
  303.                     save_cur ? lkt : NULL);
  304.             }
  305.         fclose(fp);
  306.         }
  307.         break;
  308.     default:    DispInfo(Epanel, 0, "???", Green);
  309.     }
  310. FDone:
  311. ButtonState(FButton)=FileLabel;
  312. DrawButton(FButton);
  313. return    state;
  314. }
  315.  
  316.  
  317. #ifdef    DIRECT
  318.  
  319. bool    frmchange;
  320.  
  321. #ifdef    C_TUNER
  322.  
  323. eta_scan_map(img, eta_map)
  324. Image    *img;
  325. {
  326. int    i_factor=get_iconsize(img, 0);
  327. byte    *mp[3], *srcp[3];
  328. register int    i, l, my;
  329.  
  330.     for (l=img->height; l--;)    {
  331.         mp[0] = SAVED_RLE_ROW(img, l);
  332.         if (eta_map)
  333.             srcp[0] = mp[0];
  334.         else    srcp[0] = ORIG_RLE_ROW(img, l);
  335.         for (i=1; i<img->channels; i++)
  336.             mp[i] = mp[i-1] + img->width,
  337.             srcp[i] = srcp[i-1] + img->width;
  338.         MapRGB(0, NULL, &img, srcp, mp, l, img->width, l, i_factor);
  339.     }
  340. }
  341.  
  342. MapColor(img, dp, fsize, colorp, start)
  343. Image    *img;
  344. byte    *dp;
  345. register XColor    *colorp;
  346. {
  347. XColor    TmpColor[MaxColors];
  348. int    maxdiff=img->entries;
  349. register int    i;
  350. register LKT    *lktr=lkt, *lktg=lkt+MaxColors, *lktb=lkt+(MaxColors<<1);
  351. register XColor    *tcp = TmpColor;
  352.  
  353. if (maxdiff > ncolors)
  354.     maxdiff = ncolors;    /* limitation */
  355. else if (maxdiff < 2)    return    prgmerr(0, "map 0 colors");
  356.  
  357. memcpy(tcp, colorp, sizeof(*tcp)*maxdiff);
  358.     for (i=0; i<maxdiff; i++)    {
  359.         tcp[i].red = lktr[colorp[i].red>>8] << 8;
  360.         tcp[i].green = lktg[colorp[i].green>>8] << 8;
  361.         tcp[i].blue = lktb[colorp[i].blue>>8] << 8;
  362.     }
  363. XStoreColors(img->dpy, img->colormap, tcp, maxdiff);/* load colors to VCT    */
  364. XFlush(img->dpy);
  365. #ifdef    _DEBUG_
  366. dumpColor(img->dpy, img->colormap, cquire);
  367. #endif
  368. }
  369.  
  370. #else
  371.  
  372. /*=======================================================
  373. %    important note:    Since lkt always invoked, so,    %
  374. %    even reset has to put min to lkt[0], not 0.    %
  375. =======================================================*/
  376. MapColor(img, dp, fsize, colorp, start)
  377. Image    *img;
  378. byte    *dp;
  379. register XColor    *colorp;
  380. {
  381. #ifdef    _DEBUG_
  382. time_t    t0, t1;
  383. time(&t0);
  384. #endif
  385.  
  386. register int    i;
  387. int    maxdiff = img->marray[img->fn].max - start + 1;
  388.  
  389. if (maxdiff < 1)
  390.     maxdiff = 1;
  391. /* assign data to image buffer */
  392. img->image->data = (char *) dp;
  393.  
  394. if (img->sub_img) {
  395. register int    j, min=img->marray[img->fn].min;
  396. register LKT    *lktp=lkt;
  397. register byte    *rp = dp + img->sub_img_y * img->width + img->sub_img_x;
  398.     for (i=0; i<img->sub_img_h; i++)    {
  399.     for (j=0; j<img->sub_img_w; j++)
  400.         rp[j] = lktp[(rp[j] - min)&0xFF];
  401.     XPutImage(img->dpy, img->win, img->gc, img->image,
  402.         img->sub_img_x + img->x0, img->sub_img_y + i + img->y0,
  403.         img->sub_img_x, img->sub_img_y + i, img->sub_img_w, 1);
  404.     rp += img->width;
  405.     }
  406.     img->update = True;
  407. }
  408. else if (frmchange)    {
  409.     XPutImage(img->dpy, img->win, img->gc, img->image, 0, 0, 0, 0,
  410.         img->width, img->height);
  411.     frmchange=0;
  412. #ifdef    _DEBUG_
  413.     time(&t1);
  414.     if (verbose)    message("time=%d, start=%d, end=%d\n", t1-t0, start, i);
  415. #endif
  416. }
  417. else{
  418.     for (i=start; i<maxdiff+start; i++)    {
  419.     register unsigned short    illuminance, scale=65536 / ncolors;
  420.     colorp[i].pixel = (u_long) i;
  421.     illuminance = scale * lkt[i-start];    /* set i to high byte    */
  422.     colorp[i].red = colorp[i].green = colorp[i].blue = illuminance;
  423.     colorp[i].flags = DoAll;
  424.     }
  425. /*    load colors to VCT    */
  426. XStoreColors(img->dpy, img->colormap, colorp+start, maxdiff);
  427. }
  428. XFlush(img->dpy);
  429. #ifdef    _DEBUG_
  430. dumpColor(img->dpy, img->colormap, cquire);
  431. #endif
  432. }
  433.  
  434. #endif    C_TUNER and Back_to COMMON_DIRECT
  435.  
  436. Colormap
  437. SetColormap(wa, colorp, ncolors, newmap, VcTolerance)
  438. WinAttribute    *wa;
  439. XColor    colorp[];
  440. int    ncolors;
  441. bool    *newmap;
  442. {
  443. register    i=XDisplayCells(wa->dpy, wa->screen);
  444. Colormap    cmap = DefaultColormap(wa->dpy, wa->screen);
  445.  
  446. if (wa->dpy_depth < 24)    {
  447.     if (ncolors > i)
  448.     ncolors = i;
  449.  
  450. mknew:    message("NMap = %d\n", *newmap);
  451.     if (*newmap)    VCTEntry = 24;
  452.  
  453. /* save first serveral entries for system */
  454.     for (i=0; i < VCTEntry; i++)    {
  455.     colorp[i].pixel = i;
  456.     XQueryColor(wa->dpy, cmap, &colorp[i]);
  457.     }
  458.     if (*newmap)    {
  459.     cmap = XCreateColormap(wa->dpy, wa->root, wa->visual, AllocAll);
  460.     XStoreColors(wa->dpy, cmap, colorp, ncolors); /* load colors to VCT */
  461.     }
  462.     else{
  463.     u_long    pxl, plane_masks[8];
  464.     /* number > 1 will get trouble. It is a bug. So take time do loop */
  465.     for (i=VcTolerance; i<ncolors; i++)
  466.     if (!XAllocColorCells(wa->dpy, cmap, 0, plane_masks, 0, &pxl, 1)
  467.         && ncolors-i > 4)    {
  468.         register int    j;
  469.         long    pxl[MaxColors];
  470.         msg("can't alloc C_cell %d\n", i);
  471.         i -= VcTolerance;
  472.         for (j=0; j<i; j++)
  473.             pxl[j] = colorp[j+VcTolerance].pixel;
  474.         XFreeColors(wa->dpy, cmap, pxl, j, 0);
  475.         --*newmap;
  476.         goto    mknew;
  477.     }
  478.     else    colorp[i].pixel = pxl;
  479.     XStoreColors(wa->dpy, cmap, colorp+VcTolerance, ncolors-VcTolerance);
  480.     }
  481.     if (*newmap && ncolors > 254 && arrow)
  482.     XRecolorCursor(wa->dpy, arrow, colorp[255], colorp[254]);
  483.     if (verbose)
  484.     message("[%d] grey level %d\n", cmap, ncolors-VcTolerance);
  485.     dumpColor(wa->dpy, cmap, cquire);
  486.     XInstallColormap(wa->dpy, cmap);
  487. }
  488. return (wa->cmap=cmap);
  489. }
  490.  
  491. #else    /* B/W regular routines */
  492.  
  493. Colormap
  494. SetColormap(wa, colorp, ncolors, newmap, DoQuant)
  495. WinAttribute    *wa;
  496. XColor    colorp[];
  497. int    *ncolors;
  498. bool    *newmap;
  499. {
  500. register    i=XDisplayCells(wa->dpy, wa->screen);
  501. Colormap    newcmap, cmap = DefaultColormap(wa->dpy, wa->screen);
  502.  
  503. if (wa->dpy_depth < 24)    {
  504.     if (*ncolors > i)
  505.     *ncolors = i;
  506.  
  507.     if (DoQuant){
  508.     newcmap = XCopyColormapAndFree(wa->dpy, cmap);
  509.     XFreeColormap(wa->dpy, newcmap);
  510.     *newmap = 0;
  511.     }
  512.     if (*newmap && wa->dpy_depth < 24)    {
  513.     cmap = XCreateColormap(wa->dpy, wa->root, wa->visual, AllocAll);
  514.     XStoreColors(wa->dpy, cmap, colorp, *ncolors);/* load VCT colors */
  515.     XInstallColormap(wa->dpy, cmap);
  516.     if (*ncolors > 254 && arrow)
  517.         XRecolorCursor(wa->dpy, arrow, colorp[255], colorp[254]);
  518.     } else {
  519.     for (i=0; i < *ncolors; i++) {
  520.         if (!XAllocColor(wa->dpy, cmap, &colorp[i])){
  521.         if((colorp[i].pixel=GetCloseColor(wa->dpy, cmap, *ncolors,
  522.             colorp[i].red>>8, colorp[i].green>>8, colorp[i].blue>>8))
  523.             >0)    continue;
  524.         if (*ncolors-i < *ncolors>>ToleranceFactor+1){
  525.             for (i++; i<*ncolors; i++)
  526.                 colorp[i].pixel = colorp[i-1].pixel;
  527.             break;
  528.         }
  529.     /* free allocated entries in cmap */
  530.         newcmap = XCopyColormapAndFree(wa->dpy, cmap);
  531.         XFreeColormap(wa->dpy, newcmap);
  532.         *ncolors >>= 1+quant;
  533.         *ncolors = CreateCLT(colorp, *ncolors, DoAll, quant, True, &histinfo);
  534.         msg("try to make %d level color map\n", *ncolors);
  535.         i = -1;    /* redo */
  536.         }
  537.     }
  538.     }
  539. dumpColor(wa->dpy, cmap, cquire);
  540. }
  541. return (wa->cmap=cmap);
  542. }
  543.  
  544. MapColor(img, rp, fsize)
  545. Image    *img;
  546. register byte    *rp;
  547. register int    fsize;
  548. {
  549. register byte    *bp=img->img_buf;
  550. XColor    *color = graylevel;
  551. register int    i, min=img->marray[img->fn].min;
  552. register LKT    *lktp=lkt;
  553. int    w=img->width;
  554. #ifdef    EXTENDED_COLOR
  555. int i_fact = get_iconsize(img, 0);
  556. byte    *scan =
  557. # ifdef    USE_LAST_LINE
  558.     bp + img->image->bytes_per_line*img->height - w;
  559. # else
  560.     nzalloc(w, 1, "no8_scan");
  561. # endif
  562. #endif
  563.  
  564. if (img->sub_img)    {
  565. register int    j;
  566.     rp += img->sub_img_y * w + img->sub_img_x;
  567.     bp += img->sub_img_y * w + img->sub_img_x;
  568.     for (i=0; i<img->sub_img_h; i++)    {
  569.     j = img->sub_img_w;
  570.     if (img->dpy_depth==8)
  571.         while (j--)
  572.         bp[j] = color[dgt[lktp[(rp[j] - min)&0xFF]]].pixel;
  573.     else {
  574. #ifdef    EXTENDED_COLOR
  575.     LineScan(rp, scan, color, lktp, j, min, img->dpy_depth!=1);
  576.     Map_Scanline(img, &scan, &scan, img->sub_img_x, img->sub_img_y + i,
  577.         img->sub_img_w, i_fact);
  578. #else
  579.     goto    npseud;
  580. #endif
  581.     }
  582.     XPutImage(img->dpy, img->win, img->gc, img->image,
  583.         img->sub_img_x + img->x0, img->sub_img_y + i + img->y0,
  584.         img->sub_img_x, img->sub_img_y + i, img->sub_img_w, 1);
  585.     bp += w;
  586.     rp += w;
  587.     }
  588. } else    {
  589.     if (img->dpy_depth == 8)
  590.     for (i=0; i<fsize; i++)
  591.         bp[i] = color[dgt[lktp[(rp[i] - min)&0xFF]]].pixel;
  592.     else
  593. #ifdef    EXTENDED_COLOR
  594.     for (i=0; i<img->height; i++, rp+=w)    {
  595.         LineScan(rp, scan, color, lktp, w, min, img->dpy_depth!=1);
  596.         Map_Scanline(img, &scan, &scan, 0, i, w, i_fact);
  597.     }
  598. #else
  599. npseud:    prgmerr(DEBUGANY, "system is not compiled with non-PSEUDO color");
  600. #endif
  601.     /*    Time Consuming Work    */
  602.     XPutImage(img->dpy, img->win, img->gc, img->image, img->x0, img->y0,
  603.         0, 0, w, img->height);
  604. }
  605. #if    defined    EXTENDED_COLOR && !defined USE_LAST_LINE
  606.     free(scan);
  607. #endif
  608. }
  609.  
  610. #endif    DIRECT
  611.  
  612.  
  613.  
  614. #ifdef    C_TUNER
  615.  
  616. LoadImage(fp, imgp, name)
  617. FILE    *fp;
  618. image_information    **imgp;
  619. char    *name;
  620. {
  621. register int    i;
  622. register byte    *dp;
  623. int    state = FileLoad;
  624. image_information    *img = *imgp;
  625.  
  626. if (img)    {
  627. MType    map_index[MaxColors];
  628.     free(img->scan_data);
  629.     for (i=0; i<img->entries; i++)
  630.         map_index[i] = graylevel[i].pixel;
  631.     if (img->hist)    {
  632.     register int*    hp=img->hist;
  633.         for (i=HistoSize*img->img_channels; i--;)
  634.             hp[i] = 0;
  635.         XFreeColors(img->dpy, img->colormap, map_index, i, 0);
  636.     }
  637.     DestroyColorImage(img);
  638.     firstmap = 0;
  639.     img->name = str_save(name);
  640.     state = FileReLoad;
  641. }
  642. else    img = *imgp = zalloc(1, sizeof(*img), "rle-img");
  643.  
  644. init_img_info(img, Dpy, RLE, cmn_hd.color_dpy);
  645. img->IN_FP = fp;
  646. rw_set = False;    /* reset user color table. */
  647. init_img_flag(img);
  648. img->name = name;
  649.  
  650. #ifdef    _DEBUG_
  651.     message("marray=%u, img=%u\n", img->marray, img);
  652. #endif
  653. if ((i = get_pic(multi_hd=0, "", NULL, imgp, MGray)) < 0)
  654.     return    0;
  655.  
  656. /*==============================*
  657. *    it also sets fsize    *
  658. *==============================*/
  659. if (!Find_min_max(img, histinfo.histp=img->hist, img->data, Yes, 0))
  660.     return    state;    /* no tuner can be performed    */
  661. if (fButton)    {
  662.     img->RGB = ButtonState(fButton) = ButtonSync;
  663.     img->setscale = ButtonState(hButton)==HistScaleSet;
  664.     img->update = ButtonState(DButton) =DataAnalys;
  665.     ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  666.     ResetORange(img);
  667.     DrawPanel();
  668. }
  669. img->curve = ETALinear;
  670. new_curve(lkt, histinfo, img->marray, img->curve, 0, img, img->w*img->h);
  671.  
  672. message("%s is %d(r) x %d(c) x %d(n) -- %d\n",
  673.     name, img->h, img->w, img->img_num, fsize);
  674.  
  675. if (img->dpy_depth < 24)
  676.     MapColor(img, img->scan_data, fsize,
  677.     graylevel, MAX(VCTEntry, img->marray[img->RGB%3].min));
  678. HistoHandle(img, &histinfo, Yellow);
  679. return    state;
  680. }
  681.  
  682.  
  683. CreateColorTuner(dpy, dpy1, img, create_panel, map_panel, set_gray)
  684. Display    *dpy, *dpy1;
  685. image_information    *img;
  686. {
  687. static    cct_set, cct;
  688. if (!cct_set++)    {
  689.     Set_Monitor(Monitor, dpy, dpy1, img->colormap);
  690.     VCTEntry = GetVctEntry(Dpy, Screen, Monitor[0].cmap, set_gray);
  691.     Light = GetGray(dpy, img->colormap, ncolors, 224);
  692. }
  693. if (create_panel && !cct++) {
  694.     I_ED.copy = nzalloc(sizeof(*I_ED.copy), 1, "I_copy");
  695.     map_panel = CreateTuner(img, 5, darkGray, map_panel);
  696.     img->curve = ETALinear;
  697. }
  698. return    create_panel;
  699. }
  700.  
  701. #else    /* B-W handlers */
  702.  
  703. LoadImage(fp, imgf, name)
  704. FILE*    fp;
  705. Image    **imgf;    /* must be a double pointer */
  706. char    *name;
  707. {
  708. int    frames=(*imgf) ? (*imgf)->frames : 0, state=FileReLoad;
  709. register int    i;
  710. register Image    *img;
  711.  
  712. cursor = XCreateFontCursor(Dpy, XC_umbrella);
  713.  
  714. cmn_hd.IN_FP = fp;    cmn_hd.in_type = IMAGE_INIT_TYPE;
  715. if ((*cmn_hd.header_handle)(HEADER_READ, &cmn_hd, 0, 0, False))
  716.     return    False;
  717.  
  718. if (cmn_hd.in_form != IFMT_BYTE && !WaitOk(cmn_hd.frames & -8 ? AbortButt : 0,
  719.     "images isn't in byte format", 0))    return    False;
  720.  
  721. cmn_hd.o_form = IFMT_BYTE;
  722. cmn_hd.pxl_out = 1;
  723.  
  724. if (fsize*frames != row*cln*frm)    {
  725.     if (*imgf && (*imgf)->win) {
  726.         DestroyImage(*imgf);
  727.         state = FileReLoad;
  728.     }
  729.     else    state = FileLoad;
  730.     BuildImage(imgf, name, cln, row, frames!=frm ? frm : 0,
  731.         cmn_hd.in_type, HIPS, IBNeed);
  732.     cmn_hd.data = NULL;
  733. }
  734. else    cmn_hd.data = (*imgf)->data;
  735.  
  736. img = *imgf;
  737. histinfo.histp = img->hist;
  738. img->colormap = Monitor[0].cmap;
  739. img->channels = img->dpy_channels = 1;
  740. img->history = cmn_hd.history;
  741. cmn_hd.parts = img->parts;
  742. cmn_hd.stack_num = img->stack_num;
  743. memcpy(&img->superimpose, &cmn_hd.superimpose, 6 + 11*sizeof(int));
  744. if (cmn_hd.desc)
  745.     img->desc = str_save(cmn_hd.desc);
  746. #ifdef    _DEBUG_
  747. message("buf=%u, marray=%u, img=%u\n", img->data, img->marray, img);
  748. #endif
  749.  
  750. fsize = img->width * img->height;
  751. cmn_hd.load_all = img->frames = frm;
  752. (cmn_hd.std_swif)(FI_LOAD_FILE, &cmn_hd, 0, 0, False);
  753. fclose(fp);    (*imgf)->data = cmn_hd.data;
  754.  
  755. /*===============================================================
  756. %    compute the min, max, if allocating img->hist here,    %
  757. %    scale Global hist to img->hist + HistoSize*i        %
  758. %    after histogram return. (using for loop HistoSize times    %
  759. %  for loop do checking first and finish 0 out with i = -1    %
  760. ===============================================================*/
  761. for (i=img->frames; i--;)    {
  762. register byte    *dp=img->data + i * fsize;
  763.     img->fn = i;
  764.     Find_min_max(img, histinfo.histp, dp, Yes, True);
  765. #ifdef    DIRECT
  766.     {
  767.     register int    j;
  768.     for (j=0; j<fsize; j++, dp++)
  769.         if (*dp < VCTEntry)    *dp = VCTEntry;
  770.     }
  771. #endif
  772. }
  773.  
  774. i = img->fn;    /* keep 0 all the way to the end */
  775. img->mmm = img->marray[i];
  776. SetSBarRPos(LSlider, img->linearlow=img->mmm.min, 1);
  777. SetSBarRPos(LSlider, img->linearup=img->mmm.max, 2);
  778. img->curve = ETALinear;
  779. img->setscale = ButtonState(hButton)==HistScaleSet;
  780. img->update = ButtonState(DButton) = DataAnalys;
  781. DrawButton(DButton);
  782. ChangeSlider(img, &slider, ESlider, LSlider, heqButt, EButton);
  783. SetShowFramePos(img, fButton, i);
  784. ResetORange(img);
  785. new_curve(lkt, &histinfo, img->marray, img->curve, 0, img, fsize);
  786.  
  787. message("%s is %d(r) x %d(c) x %d(f) -- %d [%d channels]\n",
  788.     name, row, cln, frm, fsize*frm, img->channels);
  789.  
  790. MapColor(img, img->data, fsize
  791. #ifdef    DIRECT
  792.     , graylevel, MAX(VCTEntry, img->marray[i].min)
  793. #endif
  794. );
  795.  
  796. img->mmm = img->marray[i];
  797. HistoHandle(img, &histinfo, lightGray);
  798.  
  799. /* select events to wait for. STRANGE ? this is not always useful  */
  800. XSelectInput(img->dpy, img->win, I_Mask | KeyPressMask |
  801.     StructureNotifyMask /*| ResizeRedirectMask*/);
  802. XSelectInput(img->dpy, img->icon, ExposureMask | StructureNotifyMask);
  803. return    state;
  804. }
  805.  
  806. #endif    C_TUNER
  807.  
  808.  
  809. ToImageStr(img, fcolor, sub_w, fh, x0, y0)
  810. Image    *img;
  811. register int    fcolor;
  812. {
  813. register int    h, y, xw, w=img->width;
  814. XImage    *ximg = XGetImage(img->dpy, img->win, x0, y0, sub_w, h=fh,
  815.         AllPlanes, img->image->format);
  816. register byte    *px = (byte *) ximg->data;
  817. byte    *p[3], *scan[3];
  818. int    ff=get_iconsize(img, 0),    pxw=ximg->bytes_per_line;
  819. long    mask24 = 0xFFFFFF;
  820. if (img->dpy_depth > 8)    {
  821.     pxw <<= 2;
  822.     fcolor = (fnt_b << 16) & (fnt_g << 8) & fnt_r;
  823.     if (ImageByteOrder(img->dpy) != LSBFirst)
  824.         mask24 <<= 8;
  825. }
  826. x0 += img->x0;    y = (y0 += img->y0);
  827.  
  828.     if (img->dpy_channels==1)    {
  829.     register byte    *pi = p[0] = img->data + y*w + x0;
  830.     scan[0] = (img->color_dpy ? img->scan_data : (byte*)img->image->data)
  831.         + y*w + x0;
  832.     for (; h--; p[0]=(pi+=w), px+=pxw, scan[0]+=w) {
  833.         for (xw=sub_w; xw--;)    {
  834.         if (img->dpy_depth > 8)    {
  835.             if (((int*)px)[xw] & mask24 != fcolor)
  836.                 continue;
  837.         } else    if (px[xw] != fcolor)    continue;
  838.         pi[xw] = fcolor;
  839.         }
  840. #    ifdef    C_TUNER
  841.         Map_Scanline(img, p, scan, x0, y++, sub_w, ff);
  842. #    else
  843.         memcpy(scan[0], px, sub_w);
  844. #    endif
  845.     }
  846.     } else {
  847.     p[0] = img->data + w*img->dpy_channels*y + x0;
  848.     scan[2] = img->scan_data + w*(img->dpy_channels*y-1) + x0;
  849.     for (; h--; px+=pxw, p[0]+=w*img->dpy_channels)    {
  850.         p[1] = p[0] + w;
  851.         p[2] = p[1] + w;
  852.         for (xw=sub_w; xw--;)    {
  853.             if (img->dpy_depth > 8)    {
  854.             if (((int*)px)[xw] & mask24 != fcolor)
  855.                 continue;
  856.             } else if (px[xw] != fcolor)    continue;
  857.             p[0][xw] = fnt_r;
  858.             p[1][xw] = fnt_g;
  859.             p[2][xw] = fnt_b;
  860.         }
  861. #    ifdef    C_TUNER
  862.         scan[0] = scan[2] + w;
  863.         scan[1] = scan[0] + w;
  864.         scan[2] = scan[1] + w;
  865.         Map_Scanline(img, p, scan, x0, y++, sub_w, ff);
  866. #    endif
  867.     }
  868.     }
  869. PlaceArea(img, x0, y0, sub_w, fh);
  870. img->update = True;
  871. XDestroyImage(ximg);
  872. }
  873.  
  874. char    *DrawShape[]={" ", "Arc", "Line", "Rectangle"};
  875.  
  876. DrawInImage(img, y0, emsg, buf)
  877. Image    *img;
  878. int    *y0;
  879. char    *emsg, *buf;
  880. {
  881. Cursor    dii_cursor=XCreateFontCursor(img->dpy, XC_crosshair);
  882. int    b, lw=1, shape=DrawsLine, x, y, si=img->o_type==HIPS,
  883.     color = AdoptColor(img, fnt_r, fnt_g, fnt_b, precision);
  884.     if (!img->color_dpy)    color >= 2;
  885. while(1)    {
  886.     XSetLineAttributes(img->dpy, img->gc, lw, 0, CapButt, 0);
  887.     b = WaitButtonPress_n_InfoImage(img, &histinfo, y0, dii_cursor);
  888.     RemoveImageEvent(img, ButtonAction)    XBell(img->dpy, 0);
  889.     if (b == Button3)    break;
  890.     if (b == Button2)    {
  891.         shape = ++shape & 3;
  892.         if (!shape)    {
  893.             shape++;
  894.             sprintf(buf, "line width = %d", lw);
  895.             Get_Note_Input(buf, 16, 8, "width ", Green, 0);
  896.             sscanf(buf, "%d", &lw);
  897.         }
  898.         DisplayMessage(NoteWin, DrawShape[shape], 4, 0);
  899.         continue;
  900.     }
  901.  
  902.     *y0 = SetParameterWin(img, img->event, img->font_h, 0);
  903.     TrackSubWin(img, &histinfo, x=img->event->xbutton.x,
  904.         y=img->event->xbutton.y, shape, Button1Mask, *y0);
  905.     DisplayMessage(NoteWin, "press MIDDLE button to comfrim", 4, 0);
  906.     b = WaitButtonPress_n_InfoImage(img, &histinfo, y0, dii_cursor)
  907.         == Button2;
  908.     XSetForeground(img->dpy, img->gc, color);
  909.     Draws(img, 0, !b, img->sub_img);
  910.     if (b)    {    /* comfirm    */
  911.         superimpose_add_elem(img, lw, color, shape, 0, 0, CapButt, 0);
  912.         if (!si) embed_image(img, lw, color, x, y);
  913.         img->update = True;
  914.     }
  915.     DisplayMessage(NoteWin, emsg, 4, img->sub_img=0);
  916. }
  917. XSetLineAttributes(img->dpy, img->gc, 0, 0, CapButt, 0);
  918. }
  919.  
  920. AdoptColor(img, r, g, b, prec)
  921. Image    *img;
  922. {
  923. register int    c = img->color_form==CFM_SCF ? CloseColor_in_Map
  924.         (img->in_cmap, img->cmaplen, r, g, b, prec) :
  925.         (RED_to_GRAY * r + GREEN_to_GRAY * g + BLUE_to_GRAY * b) >> 8;
  926. TopWindow(img, 0);
  927. Exposure_handler(img->event, img);
  928. return    c;
  929. }
  930.  
  931. embed_image(img, lw, color, x, y)
  932. register U_IMAGE*    img;
  933. register int    x, y;
  934. {
  935. register int    w=img->sub_img_w,    h=img->sub_img_h;
  936.     switch (img->sub_img)    {
  937.     case DrawsLine:
  938.         if (w < 0)    {    x += w;    w = -w;    }
  939.         if (h < 0)    {    y += h;    h = -h;    }
  940.         break;
  941.     case DrawsArc:
  942.         x = img->sub_img_x - w;
  943.         y = img->sub_img_y - h;
  944.         h <<= 1;    w <<= 1;
  945.         break;
  946.     case DrawsRect:
  947.         if (x > img->sub_img_x)
  948.             x = img->sub_img_x;
  949.         if (y > img->sub_img_y)
  950.             y = img->sub_img_y;
  951.     }
  952.     x -= lw;    y -= lw;
  953.     w += lw << 1;    h += lw << 1;
  954.     bound_check(w, x, img->width);
  955.     bound_check(h, y, img->height);
  956.     ToImageStr(img, color, w, h, x, y);
  957. }
  958.  
  959. CombineImage_Draws(img, x, y, fnt_w, fnt_h, color)
  960. Image    *img;
  961. register int    x, y, fnt_w, fnt_h;
  962. {
  963. if (img->superimpose)    {
  964. register superimpose_elems*    sip=img->superimpose[1] + img->texts;
  965.     fnt_w *= sip->cols;    fnt_h *= sip->rows;
  966. }
  967.     y -= img->ascent;
  968.     if (fnt_w + x >= img->width)
  969.         fnt_w = img->width - x - 1;
  970.     if (fnt_h + y >= img->height)
  971.         fnt_h = img->height - y - 1;
  972.     ToImageStr(img, color, fnt_w, fnt_h, x, y);
  973. }
  974.